package com.example.pattern.stream;

import java.util.*;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * @description: 流式操作
 * @project: pattern
 * @name: com.example.pattern.stream.StreamMain
 * @author: 李家东
 * @email: lijiadong@esvtek.com
 * @createTime: 2020/6/28 9:47
 * @version:1.0
 */
public class StreamMain {
    public static void main(String[] args) {

        IntStream intStream = Arrays.stream(new int[]{1, 2, 3});
        Stream<String> abcStream = Stream.of("a", "b", "c");

        Stream<Integer> integerStream = Stream.iterate(2, x -> x * 2);
        Stream<Double> doubleStream = Stream.generate(() -> Math.random());

        System.out.println("filter 过滤，返回符合条件的流对象，满足空字符串的只有一个");
        List<String> list = Arrays.asList("1", "2", "3", "4", "0", "", "33");
        Stream<String> stream = list.stream();
        long count = stream.filter(string -> string.isEmpty()).count();
        System.out.println(count);

        System.out.println("map，遍历元素并执行操作，返回执行操作后的流");
        intStream = Arrays.stream(new int[]{1, 2, 3});
        intStream.map(i -> i + 2).forEach(i -> System.out.println(i));

        System.out.println("mapToInt，遍历所有元素，返回IntStream对象，" +
                "mapToLong与mapToDouble同理");
        list = Arrays.asList("1", "2", "3", "4", "0", "", "33");
        IntStream intStream1 = list.stream().mapToInt(i -> Integer.parseInt(i));

        System.out.println("flatMap，处理流中的元素，返回新的流对象，" +
                "flatMapToInt、flatMapToLong、flatMapToDouble同理。");
        List<Student> studentList = initStudentList();
        studentList.stream().flatMap(student -> Stream.of(student.getName())).forEach(i -> System.out.println(i));

        System.out.println("distinct，去重，结果为：5");
        intStream = Arrays.stream(new int[]{1, 2, 3, 3, 2, 4, 1, 6, 3});
        System.out.println(intStream.distinct().count());

        System.out.println("sorted，排序");
        intStream = Arrays.stream(new int[]{1, 2, 3, 3, 2, 4, 1, 6, 3});
        intStream.sorted().forEach(System.out::println);

        System.out.println("peek，提取流的元素，主要用于调试使用");
        Stream.of("one", "two", "three", "four").filter(e -> e.length() > 3).peek(e -> System.out.println("Filtered value: " + e));

        System.out.println("limit，截断数据流");
        intStream = Arrays.stream(new int[]{1, 2, 3, 3, 2, 4, 1, 6, 3});
        intStream.limit(5).forEach(System.out::println);

        System.out.println("skip，跳过数据流，获取后面的元素");
        intStream = Arrays.stream(new int[]{1, 2, 3, 3, 2, 4, 1, 6, 3});
        intStream.skip(5).forEach(System.out::println);

        System.out.println("foreach，遍历元素，执行操作，省略");
        System.out.println("forEachOrdered，遍历元素，按照顺序执行操作，主要用于并行流，" +
                "因为并行流的处理顺序是不稳定的，顺序流默认就是按顺序处理");
        intStream = Arrays.stream(new int[]{1, 2, 3, 3, 2, 4, 1, 6, 3});
        intStream.parallel().forEachOrdered(System.out::println);

        System.out.println("toArray，返回数组");
        abcStream = Stream.of("a", "b", "c");
        Object[] objects = abcStream.toArray();

        abcStream = Stream.of("a", "b", "c");
//        String[] strings = abcStream.toArray(String[]::new);
        String[] strings = abcStream.toArray(size -> new String[size]);
        System.out.println(strings.length);

        System.out.println("reduce， 非常重要");
        intStream = Arrays.stream(new int[]{1, 2, 3});
        int reduce = intStream.reduce(1, Integer::sum);
        System.out.println(reduce);

        intStream = Arrays.stream(new int[]{1, 2, 3});
        reduce = intStream.reduce(2, Integer::sum);
        System.out.println(reduce);

        System.out.println("collect， 非常重要");
        intStream = Arrays.stream(new int[]{1, 2, 3});
        Map<Integer, Integer> personMap = intStream.collect(HashMap::new, (map, p) -> map.put(p, p), (m, n) -> m.putAll(n));
        personMap.forEach((key, value) -> {
            System.out.println(key+":"+value);
        });


        System.out.println("allMatch 查看所有元素是否符合特定条件，返回值为boolean");
        intStream = Arrays.stream(new int[]{1, 2, 3});
        boolean a = intStream.allMatch(i -> i % 1 == 0);
        System.out.println(a);

        System.out.println("只要有任意的元素，符合条件即可，返回boolean，每个流只能使用一次");
        intStream = Arrays.stream(new int[]{1, 2, 3});
        boolean b = intStream.anyMatch(i -> i > 2);
        System.out.println(b);

        // 返回Stream构建器
        Stream.Builder<Object> builder = Stream.builder();

        //
        intStream = Arrays.stream(new int[]{1, 2, 3});
    }

    public static <T> void printList(String description, List<T> list) {
        System.out.println(description);
        list.forEach(v -> {
            System.out.println(v.toString());
        });
    }

    public static List<Student> initStudentList() {
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student(1L, "张一山", 18, 1));
        studentList.add(new Student(2L, "李沁", 19, 2));
        studentList.add(new Student(3L, "王源", 20, 1));
        studentList.add(new Student(4L, "杨紫", 21, 2));
        studentList.add(new Student(5L, "郭麒麟", 22, 1));
        return studentList;
    }
}
